feat(component): Adds SmartScrollbar to ui-next - OHIF-2558#5924
feat(component): Adds SmartScrollbar to ui-next - OHIF-2558#5924dan-rukas wants to merge 20 commits intoOHIF:masterfrom
Conversation
✅ Deploy Preview for ohif-dev canceled.
|
platform/ui-next/src/components/SmartScrollbar/SmartScrollbarEndpoints.tsx
Outdated
Show resolved
Hide resolved
platform/ui-next/src/components/SmartScrollbar/SmartScrollbarFill.tsx
Outdated
Show resolved
Hide resolved
platform/ui-next/src/components/SmartScrollbar/SmartScrollbar.tsx
Outdated
Show resolved
Hide resolved
platform/ui-next/src/components/SmartScrollbar/SmartScrollbar.tsx
Outdated
Show resolved
Hide resolved
platform/ui-next/src/components/SmartScrollbar/SmartScrollbar.tsx
Outdated
Show resolved
Hide resolved
…ead of leaving the dot grid mounted, unmount it entirely.
platform/ui-next/src/components/SmartScrollbar/SmartScrollbar.tsx
Outdated
Show resolved
Hide resolved
platform/ui-next/src/components/SmartScrollbar/SmartScrollbar.tsx
Outdated
Show resolved
Hide resolved
… unnecessary re-renders. Memoize SmartScrollbar components to prevent unnecessary re-renders.
|
The |
Use useByteArray hook to manage the Uint8Array.
Commit hash a388084 addressed this. |
…or to pixel buckets.
|
@greptileai I just pushed bc80fae that addresses a concern we had for ensuring the fills accurately indicate marked items without over and/or under stating items that are marked. This is especially important considering that one fill is used to indicate viewed (and unviewed) medical images. Please have a look and let me know what you think. Thanks. |
…romMarked and computeContiguousRuns.
|
@greptileai I just pushed some unit tests for some of the SmartSrollbar utilities. Please have a look and let me know if there are any you think I should add. Thanks. |
|
Tested the latest code and changes and everything looks great and matches the original design and behaviors. Thanks again @jbocce for your help, changes, and detailed approach to getting this right. |
Context
This PR adds a SmartScrollbar component to
@ohif/ui-nextthat visualizes slice loading progress, viewed state, and scroll position in viewports.The component is pure UI — it has no Cornerstone or viewer dependencies. It accepts a slice index, total count, loading state, and Sets of loaded/viewed indices, and handles all measurement, animation, pointer interaction, and visual state internally.
Preview the component, animations, and behaviors here: https://ohif-scroll-design-final.netlify.app/
Changes & Results
New files — 7 component files in
platform/ui-next/src/components/SmartScrollbar/:SmartScrollbar.tsxSmartScrollbarTrack.tsxSmartScrollbarFill.tsxSmartScrollbarIndicator.tsxSmartScrollbarEndpoints.tsxutils.tsindex.tsModified —
platform/ui-next/src/components/index.tsto export the new components.Usage:
Key behaviors:
--neutral,--primary,--foreground)Testing
No Testing Needed.
This PR adds a UI component only — no viewer integration is included. The component can be previewed and tested interactively here:
Live demo: https://ohif-scroll-design-final.netlify.app/
Checklist
PR
semantic-release format and guidelines.
Code
etc.)
Public Documentation Updates
additions or removals.
Tested Environment
Greptile Summary
This PR introduces
SmartScrollbar, a pure-UI compound component for@ohif/ui-nextthat visualises slice loading progress, viewed state, and current scroll position in viewports. The implementation is self-contained with no Cornerstone or viewer dependencies, accepting avalue,total,onValueChange, andisLoadingprop alongsideUint8Array-backed fill/endpoint children.Key design choices and outcomes:
computePixelFilledFromMarkedprevents fills from overstating coverage when many slice indices map to a single pixel row.useByteArrayhook manages the mutableUint8Array+ incrementingversionpattern so fill components re-render correctly even when the array is mutated in-place; an optionaldebounceMsbatches high-frequency cache events.createPortalensuresSmartScrollbarEndpointscaps don't shift during the track contraction animation; the previously flagged ref-timing bug is fixed with auseStatecallback ref.enableKeyboardNavigation, defaultfalse) avoids conflicts with OHIF's existing keyboard shortcuts while keeping WAI-ARIA slider compliance available.ByteArrayHandleandSmartScrollbarLayoutContextValuetypes are correctly exported from the inner barrel (SmartScrollbar/index.ts) but are not forwarded from the top-levelsrc/components/index.ts, so consumers of@ohif/ui-nextcannot import these types from the package root without deep-path imports.Confidence Score: 5/5
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD SSB["SmartScrollbar\n(root — context provider,\nResizeObserver, pointer & keyboard handling)"] LC["SmartScrollbarLayoutContext\n(total, trackHeight, isLoading,\neffectiveWidth, trackWidth,\nfillPadding, stableLayerEl)"] SC["SmartScrollbarScrollContext\n(value: number)"] SSB --> LC SSB --> SC SST["SmartScrollbarTrack\n(dot-grid background,\nfades in/out with isLoading)"] SSF["SmartScrollbarFill\n(colored bars for contiguous runs;\nmarked: Uint8Array + version)"] SSI["SmartScrollbarIndicator\n(pill-shaped position marker;\nrequired child)"] SSE["SmartScrollbarEndpoints\n(SVG caps at loaded range boundaries;\nportaled into stable layer)"] LC --> SST LC --> SSF LC --> SSI LC --> SSE SC --> SSI UBA["useByteArray(size, debounceMs?)\n→ ByteArrayHandle\n(bytes, version, isFull,\nsetByte, clearByte, resetWith)"] UBA -->|"marked + version"| SSF UBA -->|"marked + version"| SSE UTILS["utils.ts\ncomputePixelFilledFromMarked()\ncomputeContiguousRuns()\ngetIndicatorLayout()"] SSF --> UTILS SSE --> UTILS SSI --> UTILS SSB --> UTILS SL["Stable layer div\n(absolute, full size,\npointerEvents: none)"] SSB --> SL SSE -->|"createPortal"| SLReviews (4): Last reviewed commit: "Add unit tests for SmartScrollbar utils ..." | Re-trigger Greptile